package xyz.xuminghai.javafx_learn.other;

import javafx.application.Application;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.SplitPane;
import javafx.scene.control.TextArea;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
import javafx.scene.text.TextFlow;
import javafx.stage.Stage;

import java.util.List;

/**
 * 2023/7/5 15:38 星期三<br/>
 * 文本比较工具
 *
 * @author xuMingHai
 */
public class TextComparisonApp extends Application {

    private final TextArea textArea1 = new TextArea();

    private final TextArea textArea2 = new TextArea();

    private final SplitPane splitPane = new SplitPane(textArea1, textArea2);

    private final BorderPane root = new BorderPane(splitPane);


    public static void main(String[] args) {
        Application.launch(args);
    }

    @Override
    public void init() {
        textArea1.setWrapText(true);
        textArea2.setWrapText(true);

        Button button = new Button("比较");
        button.setOnAction(new EventHandler<>() {

            private boolean flag;

            @Override
            public void handle(ActionEvent event) {
                if (flag) {
                    button.setText("比较");
                    ObservableList<Node> splitPaneItems = splitPane.getItems();
                    splitPaneItems.clear();
                    textArea1.clear();
                    textArea2.clear();
                    splitPaneItems.addAll(textArea1, textArea2);
                } else {
                    button.setText("重置");
                    ObservableList<Node> splitPaneItems = splitPane.getItems();
                    splitPaneItems.clear();
                    splitPaneItems.addAll(compareText(textArea1.getText(), textArea2.getText()));
                }
                flag = !flag;
            }

            private List<ScrollPane> compareText(String s1, String s2) {
                TextFlow textFlow1 = new TextFlow(new Text(s1));
                TextFlow textFlow2 = new TextFlow();
                ScrollPane scrollPane1 = new ScrollPane(textFlow1);
                // 调整节点大小匹配ScrollPane宽度
                scrollPane1.setFitToWidth(true);
                ScrollPane scrollPane2 = new ScrollPane(textFlow2);
                scrollPane2.setFitToWidth(true);

                int[] codePoints1 = s1.codePoints().toArray();
                int[] codePoints2 = s2.codePoints().toArray();
                // 最小数组长度遍历数组
                int loopCount = Math.min(codePoints1.length, codePoints2.length);
                // i 当前遍历数组索引，j 相同代码点的开始索引，k 不同代码点的开始索引
                int i = 0, j = -1, k = -1;
                for (; i < loopCount; i++) {
                    if (codePoints1[i] == codePoints2[i]) {
                        // 未赋值时对相同代码点的开始索引赋值
                        if (j < 0) {
                            j = i;
                            // 不同代码点的开始索引存在时进行处理
                            if (k >= 0) {
                                Text text = new Text(new String(codePoints2, k, i - k));
                                text.setFill(Color.RED);
                                textFlow2.getChildren().add(text);
                                k = -1;
                            }
                        }
                    } else {
                        if (k < 0) {
                            k = i;
                            if (j >= 0) {
                                textFlow2.getChildren().add(new Text(new String(codePoints2, j, i - j)));
                                j = -1;
                            }
                        }

                    }

                }

                // 最后存在未处理的部分
                if (j >= 0) {
                    textFlow2.getChildren().add(new Text(new String(codePoints2, j, i - j)));
                }

                if (k >= 0) {
                    Text text = new Text(new String(codePoints2, k, i - k));
                    text.setFill(Color.RED);
                    textFlow2.getChildren().add(text);
                }

                // 如果存在超出部分
                if (codePoints2.length > i) {
                    Text text = new Text(new String(codePoints2, i, codePoints2.length - i));
                    text.setFill(Color.RED);
                    textFlow2.getChildren().add(text);
                }

                return List.of(scrollPane1, scrollPane2);
            }


        });

        root.setTop(button);
    }


    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle(getClass().getSimpleName());
        Scene scene = new Scene(root, 800, 600);
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}
